# 处理图片
# 图片工具类
import base64
import os.path
from typing import Union
from urllib.parse import urlencode
from PIL import Image
from io import BytesIO
from fastapi import Response,Request
from common.custom_log import my_logger

# 允许的图片类型
ALLOWED_STRINGS = {"jpeg", "png", "gif"}


# 获取项目根目录
def get_root_path():
    # 获取当前文件所在目录的绝对路径
    current_dir = os.getcwd()
    return current_dir


# 获取图片格式
def get_file_contentType(format: None):
    # 根据图片格式确定MIME类型
    if format == 'jpeg':
        mime_type = 'image/jpeg'
    elif format == 'png':
        mime_type = 'image/png'
    elif format == 'gif':
        mime_type = 'image/gif'
        # 添加其他格式的处理...
    else:
        raise ValueError(f"Parameter must be a string from {ALLOWED_STRINGS}")  # 默认类型，或者抛出异常
    return mime_type


# 允许的图片格式
def check_img(s: Union[str]) -> bool:
    """
    检查字符串是否在允许的集合中。
    如果s是None，则返回True，允许None作为默认值。
    """
    return s in ALLOWED_STRINGS


# 转换图片格式
def changeFileFormat(file, saveType: str = None):
    if not check_img(saveType):
        raise ValueError(f"Parameter must be a string from {ALLOWED_STRINGS}")
    # 再内存中临时创建缓冲区，用来临时读取或者写入二进制数据，在不需要将数据持久化到磁盘上的情况下可以使用
    output_buffer = BytesIO()
    print(file.format.lower(), saveType)
    if file.format.lower() != saveType:
        if saveType == 'png':
            if file.mode != 'RGBA':
                file = file.convert('RGBA')
        else:
            if file.mode == 'RGBA':
                file = file.convert('RGB')
    file.save(output_buffer, format=saveType)
    output_buffer.seek(0)
    # 将图像数据转换为base64字符串
    # base64_string = base64.b64encode(output_buffer.getvalue()).decode()
    return output_buffer.getvalue()


# 设定图片尺寸
def changeImageSize(file, outwidth: int = None, outheight: int = None):
    if outwidth is None and outheight is None:
        return file
    width, height = file.size
    # 设置宽高
    # file.resize((new_width,new_height))
    # 使用lambda表达式来进行长宽计算
    getparam = lambda num, real: num if num is not None else real
    # 设置缩放
    file.thumbnail((getparam(outwidth, width), getparam(outheight, height)))
    return file


# 裁切图片
async def imageClip(filepath, outputMode: str = 'png', width: int = None, height: int = None):
    try:
        file = Image.open(filepath)
        filename = os.path.basename(filepath)
        # 文件后缀
        file_info = os.path.splitext(filename)
        file = changeImageSize(file, width, height)
        res = changeFileFormat(file=file, saveType=outputMode)
    except Exception as e:
        my_logger.error(e)
        return Response(status_code=404)
        # raise ValueError(f"图片格式不在指定范围内 {ALLOWED_STRINGS}")  # 默认类型，或者抛出异常
    headers = {'Content-Disposition': 'inline', 'filename': f'{file_info[0]}.{outputMode}'}
    return Response(res, headers=headers, media_type=get_file_contentType(outputMode))


# 生成url访问链接
def makeGetFileUrl(request: Request, filepath: str, query={}, path: str = 'api/upload/viewfile'):
    if len(query):
        params = f'{urlencode(query)}&filepath={filepath}'
    else:
        params = f'filepath={filepath}'
    return f'{request.base_url}{path}?{params}'